<template>
    <div class="chat-container">
      <div class="side-menu-wrapper">
        <SideMenu />
      </div>
      
      <div class="main-content">
        <!-- 中间联系人列表 -->
        <div class="contact-list">
          <div class="contact-header">
            <h3>联系人</h3>
          </div>
          <div class="contact-items">
            <div 
              v-for="contact in contacts" 
              :key="contact.id"
              :class="['contact-item', { active: currentContact?.id === contact.id }]"
              @click="selectContact(contact)"
            >
              <img :src="getAvatarUrl(contact.avatar)" class="avatar" />
              <div class="contact-info">
                <div class="name">{{ contact.nickname }}</div>
                <!-- <div class="desc">{{ contact.description }}</div> -->
              </div>
              <!-- <div class="time">{{ contact.lastTime }}</div> -->
            </div>
          </div>
        </div>
    
        <!-- 右侧聊天区域 -->
        <div class="chat-area" v-if="currentContact">
          <div class="chat-header">
            <h3>{{ currentContact.nickname }}</h3>
          </div>
          
          <!-- 聊天记录 -->
          <div class="messages-wrapper">
            <div 
              v-for="record in currentMessages?.records" 
              :key="record.askId">
              <div class="message user">
                  <div class="message-content">
                  <div class="text">{{ record.askRecord?.content }}</div>
                  </div>
              </div>
              <div class="message system">
                  <div class="message-header">
                      <img :src="currentMessages?.responder?.avatar || '@/assets/icon/qipu-avatar.png'" class="avatar" />
                      <div class="name">{{ currentMessages?.responder?.name || 'QIPU' }}</div>
                  </div>
                  <div class="message-content">
                      <div class="text">{{ record.answerRecord?.content }}</div>
                  </div>
              </div>            
            </div>
          </div>
    
          <!-- 输入区域 -->
          <div class="input-area">
            <unified-input-bar
              :isBlocking="isBlocking"
              :isVoiceMode="showVoiceInput"
              @send="handleSend"
              @voice-result="handleVoiceResult"
              @toggle-mode="showVoiceInput = !showVoiceInput"
              @stop-all="handleStopAll"
            />
          </div>
        </div>
    
        <!-- 未选择联系人时的提示 -->
        <div class="no-chat" v-else>
          <p>请选择一个联系人开始聊天</p>
        </div>
      </div>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, onMounted, nextTick, computed } from 'vue'
  import SideMenu from '@/components/SideMenu.vue'
  import { User,ListUsersResponse } from "@/types/proto/api/v1/user_service";

  import { Phase, Exchange, ListExchangesResponse, P2PExchangeRecord,ExchangeReocrdUnit,ExchageDirect, UserUnit, RecordUnit} from "@/types/proto/api/v1/exchange_service";
  import { ListExchangeRecord, DecodeExchange } from "@/api/knot";
  import { ListUsers } from "@/api/user";

  import UnifiedInputBar from '@/components/UnifiedInputBar.vue'
  import { InteractType, RagMode, ReactionType,Visibility } from '@/types/proto/common/common';
  import { CreateKnotRequest, CreateKnotChatRequest, Knot } from '@/types/proto/api/v1/knot_service';
  import { CreateKnot, CreateKnotChat, UpsertKnotReaction, DeleteKnotReaction } from '@/api/knot';
  import { getWssUrl } from '@/config';
  import { WebSocketClient} from "@/utils/websocket";
  import qipuAvatar from '@/assets/icon/qipu-avatar.png'
  const wsSocket  = ref<WebSocketClient|null>(null);
  const isPhaseEnd = ref(true)

  import { ElMessage } from 'element-plus'
  
  // 联系人列表数据

  const contacts = ref<User[]>([])

  const currentContact = ref<User | null>(null)
  const currentMessages = ref<P2PExchangeRecord|null>(null)
  const messageInput = ref<string>('')
  const messageList = ref<P2PExchangeRecord[]>([])
  const currentRcordNum = ref(0)
  const showVoiceInput = ref(false)
  const isBlocking = ref(false)
  const ragMode=ref ('')
  const pageSize = 100
  const totalContact = ref(0)

  // 选择联系人
  const selectContact = (contact:User) => {
    currentContact.value = contact
    // 这里应该调用API获取与该联系人的聊天记录
    loadMessages(contact.urn)
  }
  
  // 加载消息记录
  const loadMessages = async (userUrn:string) => {
    const filter = `responder == '${userUrn}'`
    const pageSize = 5 // 每页显示5个
    const pageToken = { limit: pageSize, offset: 0 }
    ListExchangeRecord({ pageSize: pageSize, pageToken, filter: filter }).then((res:ListExchangesResponse)=>{
      currentRcordNum.value = res.totalSize
      messageList.value=[]
      res.exchanges.map((record) => (messageList.value.push(record)))
    })
    scrollToBottom()
  }
  
  const handleStopAll = () => {
    isBlocking.value = false
  }

  const handleVoiceResult = (ask: string) => {
    console.info('voice input:', ask)
    handleSend(ask)
  }
  
  const loadUsers = () => {
    const pageToken = { limit: pageSize, offset: 0 }
    const filter = ""
    ListUsers({ pageSize: pageSize, pageToken, filter: filter }).then((res:ListUsersResponse)=>{
      totalContact.value = res.totalSize
      contacts.value=[]
      res.users.map((user) => (contacts.value.push(user)))
    }).catch(error => {
        console.error('Failed to fetch news:', error)
    })
  }
  
  const sendMessageViaWebSocket = (message: string, p: Phase = Phase.Continue, id: string = "") => {
    const chatMessage = Exchange.create({
      phase: p,
      content: message, 
      askId: id,
      mode: RagMode[ragMode.value as keyof typeof RagMode] || RagMode.RAG_MODE_UNSPECIFIED,
    });
    
    const encodedMessage = Exchange.encode(chatMessage).finish();
    if (wsSocket.value && wsSocket.value.status() === WebSocket.OPEN) {
        wsSocket.value.send(encodedMessage);
    }
  };

  const createWebSocketConnection = (knotId: string, asKId: string) => {
    let u = getWssUrl();
    const wsUrl = `${u}/${knotId}`;
    wsSocket.value = new WebSocketClient(wsUrl, {
            onMessage: onChatMessage,
        }
    );
    wsSocket.value.connect(() => {
            console.log('Connection is ready!');
            sendMessageViaWebSocket("", Phase.HELLO, asKId)
    });
  };

  const createKnotChat = async (message: string) => {
    const request = {
      chat: {
        content: message,
        interactType: InteractType.CHAT,
      }
    } as CreateKnotChatRequest;

    if (! currentMessages.value) {
      return
    }

    request.urn = currentMessages.value.rootUrn;
      if (currentContact.value) {
        request.chat?.responders.push(currentContact.value.urn)
      }

    console.log('prepare to Knot created:');
    const response = await CreateKnotChat(request);
    console.log('Knot chat created:', response);
    createWebSocketConnection(currentMessages.value?.rootUid, response.urn);
  }

  const onChatMessage = (message: any) => {
    if (! currentMessages.value) {
        return
    }
    if (currentMessages.value.records.length === 0) return;
    const res = DecodeExchange(message);
    switch (res.phase) {
        case Phase.Close:
            isPhaseEnd.value = true
            console.log('WebSocket message received phase close');
            wsSocket.value?.close();
            wsSocket.value = null;
            break;
        case Phase.End:
            isPhaseEnd.value = true
            console.log('WebSocket message received phase end:',res);
            currentMessages.value.records[currentMessages.value.records.length - 1].answerId = res.answerId;
            updateLastMessage(res.content, true, true);
            // isBlocking.value = false; 
            console.error('set isBlocking to false');
            break;
        case Phase.Continue:
            isPhaseEnd.value = false
            updateLastMessage(res.content, true);
            scrollToBottom();
            break;
        default:
            let lastMessage = currentMessages.value.records[currentMessages.value.records.length - 2];
            if (isPhaseEnd.value === true && lastMessage.askRecord?.content !== '...') {
                let askunit = {
                    content: lastMessage.askRecord?.content,
                } as RecordUnit

                let exRecord = {
                    askRecord: askunit,
                    answerRecord: {}
                } as ExchangeReocrdUnit;
                
                currentMessages.value.records.push(exRecord);
                lastMessage = currentMessages.value.records[currentMessages.value.records.length - 1];
            }

            lastMessage.askId = res.askId
            lastMessage.answerId = res.answerId
            isPhaseEnd.value = false
            console.log('WebSocket message received phase:', res.phase);
            updateLastMessage(res.content);
            break;
    }    
  }

  const createKnot = async (message: string) => {
    const request = {
      content: message,
      interactType: InteractType.CHAT,
      visibility: Visibility.TENANT,
    } as CreateKnotRequest;

    const rootUrn = ""

    console.log('prepare to Knot created:');
    CreateKnot(request).then((res:Knot) => {
        if (currentMessages.value) {
            currentMessages.value.rootUid = res.uid;
            currentMessages.value.rootUrn = res.urn;
        }
        createWebSocketConnection(res.uid, res.urn);
    })

  }

  const handleSend = async (message: string) => {
    if (isBlocking.value) {
      console.error('isBlocking is true, return')
      return
    }

    // 添加新消息到列表
    let record = {
      content: message,
      // ... 其他必要的字段
    } as RecordUnit;

    let exRecord = {
      askRecord: record,
      ragMode: RagMode[ragMode.value as keyof typeof RagMode] || RagMode.RAG_MODE_UNSPECIFIED,
    } as ExchangeReocrdUnit

    if (! currentMessages.value) {
        let responder = {name:currentContact.value?.username, urn:currentContact.value?.urn, avatar:currentContact.value?.avatar} as UserUnit
        currentMessages.value = {
        records: [],
        responder:responder,
        rootUid:'',
        rootUrn:'',
      }
    }
    const rootUrn = currentMessages.value.rootUrn

    currentMessages.value.records.push(exRecord)
    isBlocking.value = true

    if (wsSocket.value && wsSocket.value.status() === WebSocket.OPEN) {
      if (isPhaseEnd.value) {
        sendMessageViaWebSocket(message, Phase.HELLO);
      } else {
        sendMessageViaWebSocket(message);
      }
    } else {
      wsSocket.value = null;
      try {
        if (rootUrn === '') {
          createKnot(message);
        } else {
          createKnotChat(message);
        }
      } catch (error) {
        console.error('Failed to create knot:', error);
        updateLastMessage('抱歉，发生了一些错误。请稍后再试。');
      }
    }
    
    isBlocking.value = false
    scrollToBottom()
  }

  const updateLastMessage = (content: string, isAppend: boolean = false, isCompleted: boolean = false) => {
    if (! currentMessages.value) {
        return
    }

    if (currentMessages.value.records.length === 0) return;
   

    let record = currentMessages.value.records[currentMessages.value.records.length - 1].answerRecord
    if (! record) {
        record = {} as RecordUnit
        currentMessages.value.records[currentMessages.value.records.length - 1].answerRecord = record
    }
    // 更新消息显示
    if (isAppend) {
       record.content += content;
    } else {
        record.content  = content;
    }

    currentMessages.value.records[currentMessages.value.records.length - 1].answerRecord = record
    currentMessages.value.records[currentMessages.value.records.length - 1].phase = Phase.End;

    nextTick(() => {
      scrollToBottom();
    });
  };
  
  // 滚动到底部
  const scrollToBottom = () => {
    nextTick(() => {
      const container = document.querySelector('.chat-container');
      if (container) {
        container.scrollTop = container.scrollHeight;
      }
    });
  };
  
  const getAvatarUrl = (url:string) => {
    if (url === null) {
      return qipuAvatar
    }

    if (url.length === 0) {
      return qipuAvatar
    }
    return url
  }
  
  onMounted(() => {
    // 可以在这里加载初始数据
    loadUsers()
  })
  </script>
  
  <style scoped lang="scss">
  .chat-container {
    display: flex;
    height: 100vh;
    padding-top: 60px;
    background: #f5f5f5;
  }
  
  .side-menu-wrapper {
    width: 60px;
    flex-shrink: 0;
  }
  
  .main-content {
    display: flex;
    flex: 1;
    margin-left: 60px;
  }
  
  .contact-list {
    width: 280px;
    background: white;
    border-right: 1px solid #e8e8e8;
    
    .contact-header {
      padding: 20px;
      border-bottom: 1px solid #e8e8e8;
    }
  
    .contact-item {
      display: flex;
      padding: 15px;
      cursor: pointer;
      align-items: center;
      
      &:hover, &.active {
        background: #f5f5f5;
      }
  
      .avatar {
        width: 30px;
        height: 30px;
        border-radius: 50%;
        margin-right: 8px;
      }
  
      .contact-info {
        flex: 1;
        display: flex;
        align-items: center;
        
        .name {
          font-weight: 500;
          margin-bottom: 4px;
        }
  
        .last-message {
          color: #999;
          font-size: 12px;
        }
      }
  
      .time {
        color: #999;
        font-size: 12px;
      }
    }
  }
  
  .chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: white;
    margin: 0 20px;
    border-radius: 4px;
  
    .chat-header {
      padding: 20px;
      border-bottom: 1px solid #e8e8e8;
    }
  
    .messages-wrapper {
        display: flex;
        flex-direction: column;
        padding: 20px;
    }

    .message-wrapper {
        margin-bottom: 16px;
    }

    .message {
        padding: 0;

        &.system {
            display: flex;
            flex-direction: column;
            margin-bottom: 16px;
            margin-top: 8px;
        }

        &.user {
            margin-bottom: 8px;
            margin-top: 16px;
            display: flex;
            justify-content: flex-end;
            position: relative;

            .message-content {
              margin-left: 0;
              padding: 5px;
              margin-right: 0;
            }

           .text {
                background-color: #E1F5FE;
                color: #000000;
            }
        }
    }

    .message-header {
        display: flex;
        align-items: center;
        margin-bottom: 8px;

    .avatar {
        width: 24px;
        height: 24px;
        border-radius: 12px;
        margin-right: 8px;
    }

    .name {
        color: #8E8E93;
        font-size: 12px;
    }
    }

    .message-content {
    margin-left: 0;
    padding: 5px;

    .text {
        background-color: #FFFFFF;
        color: #000000;
        padding: 5px;
        border-radius: 10px;
        white-space: pre-wrap;
        word-wrap: break-word;
    }
    }

    .input-area {
        position: fixed;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 100%;
        max-width: 1200px;
        padding: 20px;
        background-color: inherit;
        z-index: 100;
        }
    }
  
  .no-chat {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
    margin: 0 20px;
    border-radius: 4px;
    color: #999;
  }
  </style>